{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 文件管理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一、文件读写\n",
    "* （1）打开文件，或者新建文件；\n",
    "* （2）读/写文件；\n",
    "* （3）关闭文件。\n",
    "Python内置了文件对象，通过open()函数即可按照指定模式打开指定文件，并创建文件对象，其语法格式如下：<br/>\n",
    "**文件对象名 = open(文件名[,打开方式])**<br/>\n",
    "![打开方式](01文件打开模式.png)  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （1）打开文件open（）方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "file = open('testfile.txt','w') #打开名为“testfile.txt”的文件，参数w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<_io.TextIOWrapper name='testfile.txt' mode='w' encoding='UTF-8'>"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （2）写文件write（）方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "26"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#向文件中输入字符串\n",
    "file.write('Interface options\\n')\n",
    "file.write('Generic options\\n')\n",
    "file.write('Miscellaneous options\\n')\n",
    "file.write('Options you shouldn’t use\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在Python中，虽然文件会在程序退出后自动关闭，但是考虑到数据的安全性，在每次使用完文件后，都需要使用close()方法关闭文件，其语法格式如下：<br/>\n",
    "**(3) 文件对象名.close()**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "file.close()  #关闭文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （4）writelines()方法\n",
    "writelines()方法用于向文件中写入一序列的字符串。这一序列字符串可以是由迭代对象产生的，如一个字符串列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "ls = ['Environment\\n','variables']      #定义列表并赋值\n",
    "with open('testfile.txt','a') as file: #以追加方式打开原有的名为“testfile.txt”的文件\n",
    "    file.writelines(ls)                #向文件中追加字符串列表"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1、read()方法\n",
    "read()方法用于从文件中读取指定的字节数，如果未给定参数或参数为负，则读取整个文件内容，其语法格式如下：<br/>\n",
    "文件对象名.read([size])，size为从文件中读取的字节数；该方法返回从文件中读取的字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Environmen\n",
      "******************************\n",
      "t\n",
      "variables\n"
     ]
    }
   ],
   "source": [
    "with open('testfile.txt','r') as file:   #以只读方式打开原有的名为“testfile.txt”的文件\n",
    "    line = file.read(10)                 #读取前10个字节\n",
    "    print(line)                          #输出前10个字节\n",
    "    print('*'*30)                        #输出30个*用于分隔\n",
    "    content = file.read()                #读取文件中剩余的所有内容\n",
    "    print(content)                        #输出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Interface options\n",
    "Generic options\n",
    "Miscellaneous options\n",
    "Options you shouldn’t use\n",
    "Environment\n",
    "variables"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2．readline()方法\n",
    "readline()方法用于从文件中读取整行，包括“\\n”字符。如果指定了一个非负数的参数，则表示读入指定大小的字符串，其语法格式如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Environment\n",
      "\n",
      "******************************\n",
      "varia\n"
     ]
    }
   ],
   "source": [
    "with open('testfile.txt','r') as file:   \n",
    "    line = file.readline()               #读取一行\n",
    "    print(line)                         \n",
    "    print('*'*30)                        \n",
    "    line = file.readline(5)             #读取下一行的前10个字符\n",
    "    print(line)                         \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3．readlines()方法\n",
    "readlines()方法用于读取所有行（直到结束符EOF）并返回列表，列表中每个元素为文件中的一行数据，其语法格式如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Environment\\n', 'variables']\n",
      "************************************************************\n",
      "Environment\n",
      "\n",
      "variables\n"
     ]
    }
   ],
   "source": [
    "with open('testfile.txt','r') as file:\n",
    "    content = file.readlines()  #读取所有行并返回列表\n",
    "print(content)  \n",
    "print('*'*60)\n",
    "for temp in content:       #遍历列表\n",
    "    print(temp)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3.只读方式打开文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Environment\n",
      "\n",
      "variables\n"
     ]
    }
   ],
   "source": [
    "with open('testfile.txt','r') as file:  #以只读方式打开原有的名为“testfile.txt”的文件\n",
    "    for line in file:    #遍历文件的所有行\n",
    "        print(line)     "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4、复制文件\n",
    "将文件“testfile.txt“中的内容复制到另一个文件“copy.txt”中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('testfile.txt','r') as file1,open('copy.txt','w') as file2:    #打开两个文件\n",
    "    file2.write(file1.read())                #将从“testfile.txt”中读取的内容写入到“copy.txt”中"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Interface options\n",
    "Generic options\n",
    "Miscellaneous options\n",
    "Options you shouldn’t use\n",
    "Environment\n",
    "variables"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 二、文件定位\n",
    "**(1)**在读写文件的过程中，如果想知道**当前文件位置指针的位置**，可以通过调用**tell()方法来获取**。tell()方法返回文件的当前位置，即文件位置指针当前位置。其语法格式如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Environm\n",
      "当前位置： 8\n",
      "ent\n",
      "\n",
      "当前位置： 12\n"
     ]
    }
   ],
   "source": [
    "with open('testfile.txt','r') as file:\n",
    "    line = file.read(8)    #读取前8个字节\n",
    "    print(line)\n",
    "    p = file.tell()     #获取指针当前位置\n",
    "    print('当前位置：',p)\n",
    "    \n",
    "    line = file.read(4)   #继续读取4个字节\n",
    "    print(line)          \n",
    "    p = file.tell()       #获取指针当前位置\n",
    "    print('当前位置：',p) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**(2)**如果在读写文件的过程中，需要**从指定的位置开始读写操作，就可以使用seek()方法**实现。seek()方法用于移动文件位置指针到指定位置，其语法格式如下：\n",
    "\n",
    "#### file. seek(offset[, whence])\n",
    "* whence：0,1,2三个参数，0表示文件开头，1表示当前位置，2表示文件结尾\n",
    "* offset:偏移量，可正可负，正数表示向后移动offset位，负数表示向前移动offset位。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入新建的文件名：bla\n",
      "test\n",
      " tes\n"
     ]
    }
   ],
   "source": [
    "filename = input('请输入新建的文件名：')    \n",
    "with open(filename,'w+') as file:          #新建文件并以读写方式打开\n",
    "    file.write('This is a test!')          \n",
    "    file.seek(10)             #指针移到从头开始的第10个字符处\n",
    "    con = file.read(4)        #读取4个字符给con\n",
    "    print(con)\n",
    "    \n",
    "    file.seek(9)             #指针移到从头开始的第9个字符处\n",
    "    con = file.read(4)        #读取4个字符给con\n",
    "    print(con)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is a test!\n"
     ]
    }
   ],
   "source": [
    "file = open('bla','r')\n",
    "content = file.read()\n",
    "print(content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b't'\n"
     ]
    }
   ],
   "source": [
    "with open('seek.txt','rb') as file:   #新建文件并以读写方式打开\n",
    "    file.seek(-2,2)                   #将文件位置指针定位到倒数第2个字符处\n",
    "    con = file.read(1)                #读取1个字符给con\n",
    "    print(con)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 三、文件与文件夹操作\n",
    "## 1、OS模块\n",
    "Python标准库的os模块除了提供使用操作系统功能和访问文件系统的简便方法之外，还提供了大量文件级操作的方法。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest222'"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os#导入os模块\n",
    "os.getcwd()#显示当前工作目录"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.mkdir('ostest')      #创建目录\n",
    "os.chdir('ostest')      #将“ostest”目录作为当前目录\n",
    "\n",
    "os.mkdir('mktest')      #在“ostest”目录中创建目录“mktest”\n",
    "\n",
    "\n",
    "f = open('1.txt','w')   #在当前工作目录下创建并打开“1.txt”文件\n",
    "f.close()               #关闭文件\n",
    "\n",
    "os.rename('1.txt','2.txt')                    #重命名文件\n",
    "os.listdir('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest')   #查看文件和目录列表\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### (1)删除目录rmdir()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.rmdir('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest/mktest')     #删除目录\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### (2)listdir()列出目录结构"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.listdir('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### (2)删除文件remove()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.remove('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest/2.txt')     #删除目录\n",
    "os.listdir('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### (3)批量修改文件名。rename()重命名文件\n",
    "在“ostest”目录下的文件名前加上编号，修改前和修改后的文件名如下图所示。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三'"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.chdir('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/')\n",
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['23333333软件.txt', '14444444通信.txt', '31111111信工.txt', 'ostest', '42222222计科.txt', 'testfile.txt']\n",
      "23333333软件.txt\n",
      "123333333软件.txt\n",
      "14444444通信.txt\n",
      "214444444通信.txt\n",
      "31111111信工.txt\n",
      "331111111信工.txt\n",
      "ostest\n",
      "4ostest\n",
      "42222222计科.txt\n",
      "542222222计科.txt\n",
      "testfile.txt\n",
      "6testfile.txt\n"
     ]
    }
   ],
   "source": [
    "#os.chdir('..')\n",
    "dir_list = os.listdir('ostest222')       #调用listdir()方法返回“ostest”目录下的文件列表\n",
    "print(dir_list)\n",
    "i=1\n",
    "os.chdir('ostest222')              #将当前工作目录切换到“ostest”目录下\n",
    "for name in dir_list:           #遍历列表\n",
    "    print(name)                 #输出原文件名\n",
    "    new_name = str(i) + name    #在原文件名前加上数字进行编号\n",
    "    i += 1\n",
    "    print(new_name)         \n",
    "    os.rename(name,new_name)    #重命名文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest222'"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['214444444通信.txt',\n",
       " '542222222计科.txt',\n",
       " '331111111信工.txt',\n",
       " '6testfile.txt',\n",
       " '4ostest',\n",
       " '123333333软件.txt']"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.listdir()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2、os.path模块提供了大量用于路径判断、文件属性获取的方法。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest222/ostest'"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os.path                #导入os.path模块\n",
    "os.path.abspath('ostest')     "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 查看绝对路径"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.chdir(\"..\")\n",
    "os.path.abspath('.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 分割目录和文件名"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三', 'ostest')"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.path.split('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三/ostest')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('9-1', '.py')"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.path.splitext('9-1.py')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a', 'b', 'c', 'd']"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'a b c d'.split()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a', 'b', 'c', 'd']"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'a,b,c,d'.split(',')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 查看文件是否存在"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.path.exists('ostest')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 查看文件大小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[Errno 2] No such file or directory: '9-1.py'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-49-e7e76939dc30>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetsize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'9-1.py'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/opt/anaconda3/lib/python3.8/genericpath.py\u001b[0m in \u001b[0;36mgetsize\u001b[0;34m(filename)\u001b[0m\n\u001b[1;32m     48\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgetsize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     49\u001b[0m     \u001b[0;34m\"\"\"Return the size of a file, reported by os.stat().\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 50\u001b[0;31m     \u001b[0;32mreturn\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mst_size\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     51\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     52\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '9-1.py'"
     ]
    }
   ],
   "source": [
    "os.path.getsize('9-1.py')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3、getatime()、getctime()和getmtime()方法\n",
    "用于获取文件的最近访问时间，创建时间和修改时间。不过返回值是浮点型秒数，可用time模块的gmtime()或localtime()方法换算。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三'"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os.path\n",
    "import time\n",
    "os.chdir('/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三')\n",
    "# os.listdir()\n",
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "testfile.txt被访问时间为: 15 Oct 2021 08:56:03\n"
     ]
    }
   ],
   "source": [
    "temp = time.localtime(os.path.getatime('testfile.txt'))\n",
    "print('testfile.txt被访问时间为:',time.strftime('%d %b %Y %H:%M:%S',temp))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 四、shutil模块也提供了大量方法支持文件和文件夹操作。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Aiping/Desktop/计算机编程2/课件/第七周/周三'"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "import shutil"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 复制文件内容以及权限"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'copytest.txt'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "shutil.copy('testfile.txt','copytest.txt')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 递归复制文件内容及状态信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[Errno 2] No such file or directory: 'ostest'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-41-feea883df3df>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mshutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopytree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'ostest'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'copytest'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/opt/anaconda3/lib/python3.8/shutil.py\u001b[0m in \u001b[0;36mcopytree\u001b[0;34m(src, dst, symlinks, ignore, copy_function, ignore_dangling_symlinks, dirs_exist_ok)\u001b[0m\n\u001b[1;32m    553\u001b[0m     \"\"\"\n\u001b[1;32m    554\u001b[0m     \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maudit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"shutil.copytree\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msrc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdst\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 555\u001b[0;31m     \u001b[0;32mwith\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscandir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msrc\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mitr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    556\u001b[0m         \u001b[0mentries\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    557\u001b[0m     return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,\n",
      "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'ostest'"
     ]
    }
   ],
   "source": [
    "shutil.copytree('ostest','copytest')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 递归删除文件夹"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "shutil.rmtree('copytest')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 完善学生管理系统，增加保存学生信息到文件的功能和从文件中读取学生信息到程序的功能。\n",
    "\n",
    "* （1）在显示菜单列表的函数中，增加“保存数据”和“恢复数据”选项。\n",
    "* （2）增加函数，用于将学生数据保存到文件中，write()方法的参数必须是字符串类型，因此，需要将字典类型的数据强制转换为字符串后进行写入。\n",
    "* （3）增加函数，用于从文件中读取数据到变量，从文件中读取到的内容是字符串，我们需要将这些带有特定格式的字符串转换为其原来的类型，可调用eval()函数将字符串转换为字典。\n",
    "* （4）在main函数中增加输入选项。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "stuInfos=[]\n",
    "def printMenu():\n",
    "    print(\"=\"*20)\n",
    "    print(\" 学生管理系统V2.0 \")\n",
    "    print(\"1.添加学生信息\")\n",
    "    print(\"2.删除学生信息\")\n",
    "    print(\"3.显示所有学生信息\")\n",
    "    print(\"4.保存数据\")\n",
    "    print(\"5.恢复数据\")\n",
    "    print(\"0.退出系统\")\n",
    "    print(\"=\"*20)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加一个学生信息\n",
    "def addStuInfo():\n",
    "    newNum = input(\"请输入新学生的学号：\")    #提示并获取学生的学号\n",
    "    newName = input(\"请输入新学生的姓名：\")   #提示并获取学生的姓名\n",
    "    newSex = input(\"请输入新学生的性别（男/女）：\")    #提示并获取学生的性别\n",
    "    newInfo = {} #定义字典\n",
    "    \n",
    "    #赋值\n",
    "    newInfo['num'] = newNum\n",
    "    newInfo['name'] = newName\n",
    "    newInfo['sex'] = newSex\n",
    "    stuInfos.append(newInfo)     #将元素添加到列表中\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "#删除一个学生信息\n",
    "def delStuInfo(student):\n",
    "    del_num = input(\"请输入要删除的学生的学号：\")\n",
    "    for stu in student:\n",
    "        if stu['num'] == del_num:\n",
    "            student.remove(stu)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "#保存到文件\n",
    "def save_file():\n",
    "    with open('student.txt','w') as file:\n",
    "        file.write(str(stuInfos))\n",
    "        \n",
    "        \n",
    "#恢复数据\n",
    "def recover_data():\n",
    "    global stuInfos\n",
    "    with open('student.txt','r') as file:\n",
    "        content = file.read()\n",
    "        stuInfos = eval(content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "#显示所有学生信息\n",
    "def showStuInfo():\n",
    "    print(\"=\" * 20)\n",
    "    print(\"学生的信息如下:\")\n",
    "    print(\"=\" * 20)\n",
    "    print(\"序号    学号    姓名   性别\")\n",
    "    i = 1\n",
    "    #遍历存储学生信息的列表，输出每个学生的详细信息\n",
    "    for tempInfo in stuInfos:\n",
    "        print(\"%d%s%s%s\" % (i, tempInfo['num'],tempInfo['name'], tempInfo['sex']))\n",
    "        i += 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "====================\n",
      " 学生管理系统V2.0 \n",
      "1.添加学生信息\n",
      "2.删除学生信息\n",
      "3.显示所有学生信息\n",
      "4.保存数据\n",
      "5.恢复数据\n",
      "0.退出系统\n",
      "====================\n",
      "请输入功能对应的数字1\n",
      "请输入新学生的学号：001\n",
      "请输入新学生的姓名：小明\n",
      "请输入新学生的性别（男/女）：男\n",
      "====================\n",
      " 学生管理系统V2.0 \n",
      "1.添加学生信息\n",
      "2.删除学生信息\n",
      "3.显示所有学生信息\n",
      "4.保存数据\n",
      "5.恢复数据\n",
      "0.退出系统\n",
      "====================\n",
      "请输入功能对应的数字4\n",
      "====================\n",
      " 学生管理系统V2.0 \n",
      "1.添加学生信息\n",
      "2.删除学生信息\n",
      "3.显示所有学生信息\n",
      "4.保存数据\n",
      "5.恢复数据\n",
      "0.退出系统\n",
      "====================\n",
      "请输入功能对应的数字3\n",
      "====================\n",
      "学生的信息如下:\n",
      "====================\n",
      "序号    学号    姓名   性别\n",
      "1001小明男\n",
      "====================\n",
      " 学生管理系统V2.0 \n",
      "1.添加学生信息\n",
      "2.删除学生信息\n",
      "3.显示所有学生信息\n",
      "4.保存数据\n",
      "5.恢复数据\n",
      "0.退出系统\n",
      "====================\n",
      "请输入功能对应的数字0\n",
      "确定退出吗？（Yes or No）：Yes\n"
     ]
    }
   ],
   "source": [
    "#main函数控制整个程序的流程\n",
    "def main():\n",
    "    while True:\n",
    "        printMenu()              #打印功能菜单\n",
    "        key = input(\"请输入功能对应的数字\")  #获取用户输入\n",
    "        if key == '1':                       #添加学生信息\n",
    "            addStuInfo()\n",
    "        elif key == '2':                    #删除学生信息\n",
    "            delStuInfo(stuInfos) \n",
    "        elif key == '3':                    #显示学生信息\n",
    "            showStuInfo()\n",
    "        elif key == '4':\n",
    "            save_file()\n",
    "        elif key == '5':\n",
    "            recover_data()\n",
    "        elif key == '0':                    #退出循环\n",
    "            quit_con = input(\"确定退出吗？（Yes or No）：\")\n",
    "            if quit_con == 'Yes':\n",
    "                break\n",
    "main()                                      #调用main函数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
